package com.luocj.elephant.demo.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Shader;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.luocj.elephant.demo.Bean.LineChartBean;
import com.luocj.elephant.demo.R;
import com.luocj.elephant.demo.utils.Utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;


public class MyCurveChartView extends View {
    private static final String TAG = MyCurveChartView.class.getSimpleName();
    private final Path linePath;
    private final Path bgPath;
    private final Paint bgPaint;
    private Paint mPaint;
    private Paint lablePaint;
    private Paint textPaint;
    private int widthDefault;
    private int heightDefault;
    private int marginDefault;
    private int textSize;
    private ArrayList<LineChartBean> beans;
    private Paint linePaint;
    private Point[] linePoints;
    private int viewWidth;
    private int viewHeight;
    private float maxValue;
    private float minValue;
    private int mWidth, mHeight;
    private int topSpace, bottomSpace;
    private int[] points = new int[]{200, 100, 300, 20, 50,
            80, 200, 100, 300, 50,
            200, 150, 160, 100, 300,
            50, 200, 150, 300, 50,};
    private boolean isBezierLine = true;
    private boolean isClick = false;
    private int clickIndex = -1;

    private int startColor = Color.parseColor("#AABFEFFF");
    private int endColor = Color.parseColor("#FF5287F7");
    private int[] mColors = new int[2];


    public MyCurveChartView(Context context) {
        this(context, null);
    }

    public MyCurveChartView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyCurveChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        widthDefault = Utils.getScreenWidth(context);
        heightDefault = Utils.dip2px(context, 100);
        marginDefault = Utils.dip2px(context, 10);
        textSize = Utils.dip2px(context, 14);
        topSpace = bottomSpace = Utils.dp2px(context, 20);
        mColors[0] = startColor;
        mColors[1] = endColor;

        initPaint();

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyLineChart);
        ta.getDimension(R.styleable.MyLineChart_line_margin, marginDefault);
        ta.getDimension(R.styleable.MyLineChart_text_size, textSize);

        linePath = new Path();
        bgPath = new Path();

        bgPaint = new Paint();
        bgPaint.setAntiAlias(true);

        linePoints = new Point[beans.size()];

        ta.recycle();

    }

    private void initPaint() {
        beans = getLineChartBeans();
        mPaint = new Paint();
        mPaint.setStrokeWidth(Utils.dp2px(getContext(), 2));
        mPaint.setColor(Color.BLUE);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        linePaint = new Paint();
        linePaint.setStrokeWidth(5);
        linePaint.setAntiAlias(true);
        linePaint.setColor(Color.GREEN);


        lablePaint = new Paint();
        lablePaint.setColor(Color.BLACK);
        lablePaint.setAntiAlias(true);
        lablePaint.setStyle(Paint.Style.STROKE);

        /**
         * 文字画笔
         */

        textPaint = new Paint();
        textPaint.setStrokeWidth(1);
        textPaint.setColor(Color.BLACK);
        textPaint.setTextSize(Utils.dip2px(getContext(), 10));
        textPaint.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width;
        int height;

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            width = widthDefault;
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            height = heightDefault;
        }

        setMeasuredDimension(width, height);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        Log.i(TAG, "onSizeChanged: " + mHeight);
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.parseColor("#44FF0000"));
        canvas.drawColor(Color.TRANSPARENT);
        canvas.translate(0f, getHeight());//设置画布中心点垂直居中
        int subWidth = mWidth / beans.size();

//        drawBgColor(canvas, subWidth);

        int start = 0;
        int stepSpace = mWidth / beans.size();
        Point pre = new Point();
        pre.set(start, -Utils.dip2px(getContext(), beans.get(0).getyAxis()));//坐标系从0,0默认在第四象限绘制
        linePoints[0] = pre;
//        linePath.moveTo(0,0);
        linePath.lineTo(pre.x, pre.y);
        for (int i = 1; i < beans.size(); i++) {
            LineChartBean lineChartBean = beans.get(i);
            Point next = new Point();
            next.set(start += stepSpace, -(Utils.dip2px(getContext(), lineChartBean.getyAxis()) - 20));
            if (isBezierLine) {
                int cW = pre.x + stepSpace / 2 ;
                Point p1 = new Point();//控制点1
                p1.set(cW, pre.y);
                Point p2 = new Point();//控制点2
                p2.set(cW, next.y);
                linePath.cubicTo(p1.x, p1.y, p2.x, p2.y, next.x, next.y);//创建三阶贝塞尔曲线
            } else {
                linePath.lineTo(next.x, next.y);
            }
            pre = next;
            linePoints[i] = next;
        }

//        linePath.lineTo(pre.x, 0);
//        linePath.close();
//        LinearGradient hrLg = new LinearGradient(0,0, 0,-getHeight(), Color.BLUE,Color.BLUE, Shader.TileMode.CLAMP);
//        mPaint.setShader(hrLg);
        canvas.drawPath(linePath, mPaint);

    }

    /**
     * 画背景
     *
     * @param canvas
     * @param subWidth
     */
    private void drawBgColor(Canvas canvas, int subWidth) {
        LinearGradient hrLg = new LinearGradient(0, 0, beans.get(beans.size() - 1).getxAxis() * subWidth, 0, Color.RED, Color.YELLOW, Shader.TileMode.CLAMP);
        //设置垂直透明度渐变,起点坐标(x是图表中心,y是最高点的纵坐标,其值最小),终点坐标(x是图表中心,y是最低点的纵坐标,其值最大)
//        float x = yLength / 2;
//        LinearGradient vtLg = new LinearGradient(x, 0, x, getHeight(),startColor, endColor, Shader.TileMode.CLAMP);
//        Shader composeShader = new ComposeShader(hrLg, vtLg, PorterDuff.Mode.MULTIPLY);
        bgPath.moveTo(0, 0);
        for (int i = 0; i < beans.size(); i++) {
            bgPath.lineTo(beans.get(i).getxAxis() * subWidth, -Utils.dip2px(getContext(), beans.get(i).getyAxis()));
        }
        bgPath.lineTo(beans.get(beans.size() - 1).getxAxis() * subWidth, 0);
        bgPath.close();
        bgPaint.setShader(hrLg);
        canvas.drawPath(bgPath, bgPaint);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float touchX = event.getX();
        for (int i = 0; i < beans.size(); i++) {
            int perWidth = getWidth() / beans.size();
            if (Math.abs(touchX - i * perWidth) < 20) {
                isClick = true;
                clickIndex = i;
                if (onTouchListener != null) {
                    onTouchListener.OnPointTouch((int) beans.get(i).getyAxis());
                }
            }
        }
        return true;
    }

    public interface OnPointTouch {
        void OnPointTouch(int clickIndex);
    }

    private OnPointTouch onTouchListener;

    public void setOnTouchListener(OnPointTouch onTouchListener) {
        this.onTouchListener = onTouchListener;
    }

    @NonNull
    private ArrayList<LineChartBean> getLineChartBeans() {
        //获取数据
        ArrayList<LineChartBean> beans = new ArrayList<>();
        for (int i = 0; i < points.length; i++) {
            LineChartBean lineChartBean = new LineChartBean();
            lineChartBean.setxAxis(i);
            lineChartBean.setyAxis(points[i]);
            beans.add(lineChartBean);
        }

        maxValue = Collections.max(beans, new Comparator<LineChartBean>() {
            @Override
            public int compare(LineChartBean o1, LineChartBean o2) {
                return (int) (o1.getyAxis() - o2.getyAxis());
            }
        }).getyAxis();

        minValue = Collections.min(beans, new Comparator<LineChartBean>() {
            @Override
            public int compare(LineChartBean o1, LineChartBean o2) {
                return (int) (o1.getyAxis() - o2.getyAxis());
            }
        }).getyAxis();


        return beans;
    }

    /**
     * x 轴
     *
     * @param canvas
     */
    private void drawXLable(Canvas canvas) {
        int width = getWidth() - 40;
        float subWidth = width / 10;
        for (int i = 1; i <= 10; i++) {
            canvas.drawText(i + "", (i - 1) * subWidth + 20, -30, textPaint);
        }

    }

    private void drawXLine(Canvas canvas) {
        canvas.drawLine(10, -100, getRight(), -100, mPaint);
    }

    private void drawYLine(Canvas canvas) {
        canvas.drawLine(10, -100, 10, -getBottom(), mPaint);
    }

    private void drawYLable(Canvas canvas) {

    }

    public void updataView(LineChartBean lineChartBean) {
        Log.i(TAG, "updataView: yVaule" + lineChartBean.getyAxis());
        beans.add(lineChartBean);
        beans.remove(0);
        linePath.reset();
        requestLayout();
        postInvalidate();
    }
}
